import traceback
from typing import Optional
from sqlalchemy.orm import Session
from sqlalchemy.sql import func
from app.common.enums.resp_enum import ErrTypes
from app.common import exceptions
from app.models.merchant import Merchant, MerchantFee, MerchantKey
from app.models.factor import Factor, FactorFee
from app.models import PayProduct

import logging
logger = logging.getLogger(__name__)

def get_merchants(db: Session, skip: int = 0, limit: int = 10):
    return db.query(Merchant).order_by(Merchant.create_time.desc()).offset(skip).limit(limit).all()

def get_merchant_info(db: Session, params: dict):
    merc_no = params.get('merc_no')
    return db.query(Merchant).filter(Merchant.merc_no == merc_no).first()

#def get_merchant_fees(db: Session, merc_no: str, product_code: str = None):
def get_merchant_fees(db: Session, params: dict):
    try:
        merc_no = params.get('merc_no')
        if not merc_no:
            raise exceptions.GenericException(error_type=ErrTypes.bz_param_validation_error)
        product_code = params.get('product_code')
        query_set = db.query(MerchantFee).filter(MerchantFee.merc_no == merc_no)
        if product_code:
            query_set = query_set.filter(MerchantFee.product_code == product_code)
        return query_set.order_by(MerchantFee.create_time.desc()).all()
    except Exception as err:
        logger.error(traceback.print_exc)
        raise exceptions.GenericException(ErrTypes.db_query_error)

def get_merchant_fees_by_pay_type(db: Session, merc_no: str, pay_type: int):
    try:
        results = MerchantFee.query.join(PayProduct, PayProduct.product_code == MerchantFee.product_code). \
            filter(PayProduct.pay_type == pay_type). \
            with_entities(MerchantFee.product_code, MerchantFee.product_name, 
                          MerchantFee.pay_channel_code, PayProduct.pay_type).all()
        return results
    except Exception as err:
        logger.error(traceback.print_exc)
        raise exceptions.GenericException(ErrTypes.db_query_error)

def get_merchant_fee(db: Session, merc_no: str, product_code: str, fee_mode: Optional[int]=None):
    pass

def get_merchant_fee_old(db: Session, merc_no: str, product_code: str, fee_mode: Optional[int]=None):
    try:
        merc_fee = db.query(MerchantFee).filter(
            MerchantFee.merc_no == merc_no,
            MerchantFee.product_code == product_code
        ).first()
        return merc_fee
    except Exception as err:
        logger.error(traceback.print_exc)
        raise exceptions.GenericException(ErrTypes.db_query_error)
    


#def get_merchant_by_id(db: Session, merc_id: int):
#    return db.query(Merchant).filter(Merchant.fid == merc_id).first()


# merchant_key
def get_merc_key(db: Session, merc_no: str):
    return db.query(MerchantKey).filter(MerchantKey.merc_no == merc_no).first()

